
import csv

from django.db import transaction
from django.http import HttpResponse
from django.urls import reverse_lazy
from django.shortcuts import render, redirect

from django.contrib.auth import login
from django.contrib.auth.views import LoginView
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.mixins import LoginRequiredMixin

from django.views import View
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView

from .models import Task
from .forms import PositionForm


class CustomLoginView(LoginView):
    template_name = 'register_app/login.html'
    redirect_authenticated_user = True
    fields = '__all__'

    def get_success_url(self):
        return reverse_lazy('tasks')


class RegisterPage(FormView):
    template_name = 'register_app/register.html'
    form_class = UserCreationForm
    redirect_authenticated_user = True
    success_url = reverse_lazy('tasks')

    def form_valid(self, form):
        user = form.save()
        if user is not None:
            login(self.request, user)
        return super(RegisterPage, self).form_valid(form)

    def get(self, *args, **kwargs):
        if self.request.user.is_authenticated:
            return redirect('tasks')
        return super(RegisterPage, self).get(*args, **kwargs)


class TaskList(LoginRequiredMixin, ListView):
    model = Task
    context_object_name = 'tasks'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['tasks'] = context['tasks'].filter(user=self.request.user)
        context['count'] = context['tasks'].filter(absent=False, present=False).count()

        search_input = self.request.GET.get('search-area') or ''
        # using or/and in this way(variable = x or y) is bad habit
        #   >>> 0 or [[]]
        #   [[]]
        #   >>> 1 and [[]]
        #   [[]]
        # and get can take optional parameter
        #   >>> {}.get(1, 'hello')
        #   'hello'
        # search_input = self.request.GET.get('search-area', '')
        if search_input:
            context['tasks'] = context['tasks'].filter(
                student_name__contains=search_input)

        context['search_input'] = search_input

        return context


class TaskDetail(LoginRequiredMixin, DetailView):
    model = Task
    context_object_name = 'task'
    template_name = 'register_app/task.html'


class TaskCreate(LoginRequiredMixin, CreateView):
    model = Task
    fields = ['student_name', 'title', 'lesson_date',
              'description', 'present', 'absent']
    success_url = reverse_lazy('tasks')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(TaskCreate, self).form_valid(form)


class TaskUpdate(LoginRequiredMixin, UpdateView):
    model = Task
    fields = ['student_name', 'title','lesson_date',
              'description', 'present', 'absent']
    success_url = reverse_lazy('tasks')


class DeleteView(LoginRequiredMixin, DeleteView):
    model = Task
    context_object_name = 'task'
    success_url = reverse_lazy('tasks')

    def get_queryset(self):
        owner = self.request.user
        return self.model.objects.filter(user=owner)


class TaskReorder(View):
    def post(self, request):
        form = PositionForm(request.POST)

        if form.is_valid():
            positionList = form.cleaned_data["position"].split(',')

            with transaction.atomic():
                self.request.user.set_task_order(positionList)

        return redirect(reverse_lazy('tasks'))


def generate_csv(request):
    if request.method == 'POST':
        student_name = request.POST.get('student_name')
        tasks = Task.objects.filter(user=request.user, student_name=student_name)

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="tasks.csv"'

        writer = csv.writer(response)
        writer.writerow(['Student Name', 'Title', 'Lesson Date', 'Description', 'Absent', 'Present'])

        for task in tasks:
            writer.writerow([task.student_name, task.title, task.lesson_date, task.description, task.absent, task.present])

        return response

    return render(request, 'generate_csv.html')
